﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Xml;
using AgilePlannerDT.Data;
using AgilePlannerDT.Utils;

namespace AgilePlannerDT.Persister.Impl.Socket
{
    public class OutboundConnection
    {
        protected IConnection connection;
        protected MemoryStream memoryStream;
        protected XmlTextWriter writer;
        protected XMLSocketClient client;
        protected ManualResetEvent manualEvent = new ManualResetEvent(false);
        protected StreamWriter sender;
        protected StringBuilder xml;
        protected XmlWriterSettings settings;
        protected InboundConnection inbound;
        
        public OutboundConnection(IConnection connection, XMLSocketClient client)
        {

            this.connection = connection;
            this.memoryStream = new MemoryStream(0);
            
            this.client = client;
       
            this.writer = new XmlTextWriter(memoryStream,Encoding.UTF8);
            this.writer.Formatting = System.Xml.Formatting.Indented;
            this.writer.Flush();
            this.memoryStream.Flush();
            inbound = new InboundConnection(connection, client);
            Thread receiveThread = new Thread(inbound.Listen);
            receiveThread.Start();
        }

        public static byte[] lengthify(byte[] array)
        {
            byte[] msg = array;
            byte[] length = NumberConverter.marshall(msg.Length);
            byte[] lengthified_msg = new byte[msg.Length + 8];

            Array.Copy(length, 0, lengthified_msg, 0, 8);
            Array.Copy(msg, 0, lengthified_msg, 8, msg.Length);
            return lengthified_msg;
        }

        public void Send(Message msg)
        {
            memoryStream.SetLength(0);
            msg.WriteXml(this.writer);
            writer.Flush();
            
            try
            {
                connection.send(lengthify(memoryStream.ToArray()));
            }
            catch (IOException)
            {
                this.close();
            }
        }

        public void close()
        {
            inbound.Stop();
            this.writer.Close();
            connection.close();
        }

        private byte[] int2bytes(int length)
        {
            byte[] ret = new byte[8];
            for (int i = 7; i >= 0; i--)
            {
                ret[i] = (byte)(length & 255);
                length >>= 8;
            }
            return ret;
        }

    }
}
